import socket
import threading
import time
from queue import Queue


class LocalProxy:
    def __init__(self, local_host, local_port, remote_host, remote_port, thread_num=5):
        """初始化本地代理服务器"""
        self.local_host = local_host
        self.local_port = local_port
        self.remote_host = remote_host
        self.remote_port = remote_port
        self.thread_num = thread_num
        self.buffer_size = 8192
        self.request_queue = Queue()

    def start(self):
        """启动本地代理服务器"""
        try:
            # 创建本地监听套接字
            local_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            local_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            local_socket.bind((self.local_host, self.local_port))
            local_socket.listen(5)
            print(f"本地代理服务器已启动: {self.local_host}:{self.local_port}")

            # 启动工作线程
            for i in range(self.thread_num):
                thread = threading.Thread(target=self._worker)
                thread.daemon = True
                thread.start()

            # 开始接受客户端连接
            while True:
                client_socket, client_address = local_socket.accept()
                print(f"接受来自 {client_address} 的连接")
                self.request_queue.put(client_socket)

        except Exception as e:
            print(f"启动代理服务器时出错: {e}")

    def _worker(self):
        """工作线程函数，处理客户端请求"""
        while True:
            client_socket = self.request_queue.get()
            try:
                # 创建与远程服务器的连接
                remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                remote_socket.connect((self.remote_host, self.remote_port))

                # 启动数据转发线程
                client_to_remote = threading.Thread(
                    target=self._forward_data,
                    args=(client_socket, remote_socket, "客户端到服务器")
                )
                remote_to_client = threading.Thread(
                    target=self._forward_data,
                    args=(remote_socket, client_socket, "服务器到客户端")
                )

                client_to_remote.daemon = True
                remote_to_client.daemon = True
                client_to_remote.start()
                remote_to_client.start()

            except Exception as e:
                print(f"处理客户端请求时出错: {e}")
                if client_socket:
                    client_socket.close()

    def _forward_data(self, source, destination, direction):
        """在源和目标之间转发数据"""
        try:
            while True:
                data = source.recv(self.buffer_size)
                if len(data) == 0:  # 连接已关闭
                    break

                # 在这里可以实现数据优化，例如压缩、缓存等加速技术
                # 简单示例：添加时间戳来测量延迟
                timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
                print(f"[{timestamp}] {direction} 转发数据: {len(data)} 字节")

                destination.sendall(data)

        except Exception as e:
            print(f"数据转发时出错 ({direction}): {e}")
        finally:
            # 关闭连接
            source.close()
            destination.close()


if __name__ == "__main__":
    # 配置本地代理服务器参数
    local_proxy = LocalProxy(
        local_host="127.0.0.1",  # 本地监听地址
        local_port=8080,  # 本地监听端口
        remote_host="example.com",  # 远程服务器地址
        remote_port=80,  # 远程服务器端口
        thread_num=10  # 工作线程数量
    )

    # 启动代理服务器
    local_proxy.start()
